package workflow

import "context"

// DagErrorCode Dag错误码
type DagErrorCode string

const (
	// ErrReplicateEdge dag 边界重复定义
	ErrReplicateEdge DagErrorCode = "dag 边界重复定义"
	// ErrNoVertex dag 没有顶点集
	ErrNoVertex DagErrorCode = "dag 没有顶点集"
	// ErrHasCyclic dag 有环路
	ErrHasCyclic DagErrorCode = "dag 有环路"
	// ErrHasMultipleStartNodes 有多个开始节点
	ErrHasMultipleStartNodes DagErrorCode = "dag 有多个开始节点"
	// ErrReplicateNode 有重复顶点集合
	ErrReplicateNode DagErrorCode = "dag 节点重复定义"
	// ErrReplicateDependency 有重复依赖关系
	ErrReplicateDependency DagErrorCode = "dag 有重复依赖关系"
)

// Dag Dag图
type Dag struct {
	ID         string              `json:"ID"`         // Dag图ID
	NodeMap    map[string]*DagNode `json:"NodeMap"`    // Dag所有节点映射集合
	ParentNode *DagNode            `json:"ParentNode"` // 父节点

	startNode *DagNode // 开始节点
	endNode   *DagNode // 结束节点
	hasBranch bool     // 是否包含分支
	hasEdge   bool     // 是否包含边界

	hasForwarding   bool // 是否数据转发
	forwardingCount int  // 数据转发节点数量
	nodeIndex       int  // 节点索引
}

// DagNode Dag节点
type DagNode struct {
	ID            string                   `json:"ID"` // 节点ID
	index         int                      // 节点索引
	subDag        *Dag                     // 子Dag
	conditions    map[string]*Dag          // 条件节点
	operations    []IOperation             // 节点Actions
	isDynamic     bool                     // 是否动态子Dag节点
	aggregator    AggregatorType           // 节点数据聚合器
	forwarder     map[string]ForwarderType // 节点数据转发器
	foreach       ForeachType              // 节点数据遍历器
	condition     ConditionType            // 节点条件器
	parentDag     *Dag                     // 父Dag
	inDegree      int                      // 顶点 dag 入度
	outDegree     int                      // 顶点 dag 出度
	dynamicDegree int                      // 动态节点入度
	children      []*DagNode               // 子节点集
	dependencies  []*DagNode               // 依赖节点集

	next []*DagNode // 下游节点集
	prev []*DagNode // 上游节点集

}

// AggregatorType 节点数据聚合器的聚合器定义类型
type AggregatorType func(map[string][]byte) ([]byte, error)

// ForwarderType 节点数据转发器的转发器定义
type ForwarderType func([]byte) []byte

// ForeachType 节点数据遍历器的遍历器定义
type ForeachType func([]byte) map[string][]byte

// ConditionType 节点条件器的条件定义
type ConditionType func([]byte) []string

// IOperation 操作接口定义
type IOperation interface {
	// GetID 获取节点ID
	GetID() string
	// EncodeJson 编码为JSON格式
	EncodeJson() []byte
	// GetProperties 获取属性
	GetProperties() map[string][]string
	// Execute Execute执行一个操作，executor可以通过配置
	Execute(ctx context.Context, data []byte, conf map[string]interface{}) ([]byte, error)
}

// PipelineErrorHandler 错误处理器
type PipelineErrorHandler func(err error) ([]byte, error)

// PipelineHandler 节点处理器
type PipelineHandler func(ctx context.Context, data string)

// Pipeline 节点管道
type Pipeline struct {
	Dag                  *Dag                 `json:"-"`
	ExecutePosition      map[string]string    `json:"ExecutePosition"`      // 当前执行位置
	ExecuteDepth         int                  `json:"ExecuteDepth"`         // 执行深度
	CurrentDynamicOption map[string]string    `json:"CurrentDynamicOption"` // 当前动态参数
	FailureHandler       PipelineErrorHandler `json:"-"`                    // 错误处理器
	PipelineHandler      PipelineHandler      `json:"-"`                    // 节点处理器
}
